package pl.accuratus.exmore.client.spi;

import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.Map;

public class AnnotationParameterHolder {
	class Parameters {
		private final Map<String, Object> map = new HashMap<String, Object>();

		public void add(String name, Object value) {
			map.put(name, value);
		}

		public Map<String, Object> getAll() {
			return new HashMap<String, Object>(map);
		}
	}

	class AnnotationParameters {
		private final Map<Class<? extends Annotation>, Parameters> map = new HashMap<Class<? extends Annotation>, Parameters>();

		public void add(Class<? extends Annotation> clazz, Parameters params) {
			map.put(clazz, params);
		}

		public Map<Class<? extends Annotation>, Parameters> getAll() {
			return new HashMap<Class<? extends Annotation>, Parameters>(map);
		}

		public Parameters get(Class<? extends Annotation> annotation) {
			return map.get(annotation);
		}
	}

	private final Map<Class<?>, AnnotationParameters> map = new HashMap<Class<?>, AnnotationParameters>();

	public void addParameter(Class<?> classWithAnnotation, Class<? extends Annotation> annotation, String paramName,
			Object paramValue) {
		if (classWithAnnotation == null || annotation == null || paramName == null)
			throw new IllegalArgumentException();

		AnnotationParameters classAnnotations = map.get(classWithAnnotation);
		if (classAnnotations == null)
			map.put(classWithAnnotation, classAnnotations = new AnnotationParameters());

		Parameters params = classAnnotations.get(annotation);
		if (params == null)
			classAnnotations.add(annotation, params = new Parameters());

		params.add(paramName, paramValue);
	}

	public Map<String, Object> getParameters(Class<?> classWithAnnotation, Class<? extends Annotation> annotation) {
		AnnotationParameters classAnnotations = map.get(classWithAnnotation);
		if (classAnnotations == null)
			return null;
		Parameters params = classAnnotations.get(annotation);
		if (params == null)
			return null;
		return params.getAll();
	}
}
